#include "stdafx.h"
#include "Keylistner.h"
#include "AddNodeDialog.h"
#include "iostream"
#include "SaveTo.h"
#include "ReadFrom.h"
#include "Paste.h"
#include "GetFile.h"
#include "ERR.h"




using namespace RedDot;
using namespace System::Runtime::InteropServices;
[DllImport("shell32.dll")]
	 IntPtr ShellExecute(
    IntPtr hwnd,
    string lpOperation,
    string lpFile,
    string lpParameters,
    string lpDirectory,
    int nShowCmd);

Keylistner::Keylistner(System::Windows::Forms::KeyEventArgs^ e)
{
	//E=e->KeyData;
	tField=false;
	posH = 0;
	posV = 0;
	nazwa = "";
	

}

Keylistner::Keylistner(Root *tr,int otab,int stepss,int max,int uniqueNo)
{
	tree=tr;
	wezel=(Node*)tr;
	shift=false;
	control=false;
	tField=false;
	modified = false;
	posH = 0;
	posV = 0;
	podswietlony=NULL; 
	nazwa = "";
	steps = stepss;
	ctab=otab;
	maxsteps=max;
	uniq = uniqueNo;
	appPath = (char*)(void*)Marshal::StringToHGlobalAnsi(Environment::CurrentDirectory);


}
//Bury 10.04.07 od
//funkcja edytujaca nody - info w Keylistner.h
void Keylistner::editNode(Node* wezel)
{
	AddNodeDialog ^dialog2 = gcnew AddNodeDialog(2,tree,wezel,wezel->getNodeName());//gdy pierwszym argumentem jest "2" to edycja
	dialog2->ShowDialog();
//	modified = true;

}
//kolaps
void Keylistner::savestat(){
	char filename[1024];
//	char temp[1024] = "";
	
	sprintf(filename,"%s\\tmp\\ur\\%ds%d.rdt",appPath,ctab,steps);
	SaveTo(filename,tree,NULL);
	//steps++;
	maxsteps++;

	//if(steps>=maxsteps)
	//{
		//maxsteps++;
	//}
	//else{
	if(steps<maxsteps){
		maxsteps=steps;
		
	}
	modified = true;
}
//Bury 10.04.07 do

void Keylistner::KeyDown(System::Windows::Forms::KeyEventArgs^ e)
{
	//System::Windows::Forms::Keys E;
	E=e->KeyCode;
/*4.05 Pawel*/	
	if(!e->Control&&!e->Alt&&!e->Shift)
	switch(E){
		case (Windows::Forms::Keys::Insert):
			{
//			Node *n1 = new Node("",System::Drawing::Color::Black.ToArgb(),true);
			if(true)
			{
				if(wezel->link==0){
				Node *tmp=new Node("",System::Drawing::Color::Black.ToArgb(),wezel->strona);
				wezel->addChild("",tmp);
			
				tField=true;
				if(wezel->strona)
					tF_X = tmp->getX();
				else 
					tF_X = tmp->getX()-100;
				tF_Y = tmp->getY();
				wezel->focus=false;
				wezel=tmp;
				edited = tmp;
				
			
				}
				
			}
			
			break;
			}
			
			
		case (Windows::Forms::Keys::V):
		case (Windows::Forms::Keys::Space):
			{
				if(wezel->father)
				{
					if(wezel->first!=NULL)	
						wezel->visibility();
				}
				else
					if(wezel->first&&wezel->first->first)
						wezel->first->visibility();


				
			}
			break;
		case (Windows::Forms::Keys::R):
			{
				bool widocznosc=false;
				if(wezel->link==true)
				{   
					char tmp[1024] = "";
					sprintf(tmp,"%s\\tmp\\net.rdt",appPath);
					GetFile(wezel->NodeName.c_str(),tmp);
					
					if(ReadFrom(tmp,NULL)!=NULL)
					{
						Node *ble=new Node("nazwa",0,true);
						while(wezel->first)
						{
							wezel->first->remove();
						}
						ble=ReadFrom(tmp,NULL);
//						ble->setInvisible();
						Node *prawe,*lewe;
						bool t=false;

//				if((ble->first->first)&&(ble->last->first))
//				{
						prawe=ble->first;
						lewe=ble->last;
						prawe->remove();
						prawe->changeNodeName("[PRAWE]");
						prawe->setColour(Color::Black.ToArgb());
						lewe->remove();
						lewe->changeNodeName("[LEWE]");
						lewe->setColour(Color::Black.ToArgb());
						t=true;
//				}
//				else
//				{
//					if(ble->first->last)
//					{
//					}
//				}
				
//				ble->strona=wezel->strona;
				
//				Paste(ble,wezel);
//				ble->setVisible();
//				ble->father=wezel;
						prawe->setInvisible();
						lewe->setInvisible();
						if(wezel->strona)
						{
							lewe->mirror();
						}
						else
						{
							prawe->mirror();
						}
/*				
				Paste(prawe,ble);
				
				Paste(lewe,ble);
*///				prawe->setVisible();
//				lewe->setVisible();
//				ble->setInvisible();
//				Paste(ble,wezel);
//				wezel=ble;
						wezel->addChild("",ble);
						ble->addChild("",prawe);
						ble->addChild("",lewe);
						prawe->focus=false;
						lewe->focus=false;
				//wezel->link=false;
						prawe->setVisible();
						lewe->setVisible();
						wezel=ble;
						wezel->link=false;
						if(wezel->previous) wezel->previous->focus=false;
						wezel->focus=1;
//						if(widocznosc)
//							ble->setVisible();
//				}
					} 
				//else{
				//	ERR ^er=gcnew ERR();
			//		er->Komunikat("Podany URL jest nieprawidlowy");
					//er->Miejsce(70,30);
		//			er->ShowDialog();
		//		}
				}
				
				//else if(wezel->link_z)
					//ShellExecute(IntPtr::Zero,"open",wezel->getNodeName(),nullptr,nullptr,SW_SHOWNORMAL);
			}
			break;
		//Bury 10.04.07 od
		case (Windows::Forms::Keys::F2)://edycja nodow za pomoca klawiatury
			{
					stepup();
					editNode(wezel);
					savestat();
			}
			break;
        //Bury 10.04.07 do
		//case (Windows::Forms::Keys::Q): {
		//		wezel->changeColour(Drawing::Color::Blue.ToArgb());
		//		savestat();
		//		break;
										   
		case (Windows::Forms::Keys::Enter):
			{  
				Node *n1 = new Node("",System::Drawing::Color::Black.ToArgb(),wezel->strona);
			
			
			
			if(wezel->father) {
			   wezel->addBrother("",n1);
			   if(wezel->strona)
					tF_X = n1->getX();
			   else
				   tF_X = n1->getX()-100;
			   tF_Y = n1->getY();
			   edited=n1;
			   tField=true;
			   wezel=n1;
			}	else {
				/*
				tF_X = wezel->last->getX();
			   tF_Y = wezel->last->getY();
			   edited=wezel->last;*/
				this->editNode(wezel);
			}	
				
				break;
			}	
		case (Windows::Forms::Keys::Up):
				wezel=wezel->inUp();
			
			break;
		case (Windows::Forms::Keys::Down):
				wezel=wezel->inDown();
			break;
		case (Windows::Forms::Keys::Right):
			{
				if(wezel->strona)
				{
					if(wezel->father)
						wezel=wezel->inRight();
					else
					{
						wezel->focus=false;
						wezel=wezel->first->inRight();
					}
				}
				else
					wezel=wezel->inLeft();
			break;
			}
		case (Windows::Forms::Keys::Left):
			{
				if(wezel->strona)
				{
					if(wezel->father)
						wezel=wezel->inLeft();
					else
					{
						wezel->focus=false;
						wezel=wezel->last->inRight();
					}
				}
				else
					wezel=wezel->inRight();

			break;
			}
//Pawel 13.03.07 od
		case (Windows::Forms::Keys::Delete):
		/*		Node *tmp=wezel;
				if(wezel->father)
				{
					wezel=wezel->remove();
					delete tmp;
				}*/

			break;
//Pawel 13.03.07 do

	}
	if(!e->Control&&e->Alt&&!e->Shift)
	{
		switch(E)
		{
			case (Windows::Forms::Keys::Up):
				stepup(); 
				wezel->move(0,3);
				savestat();
				break;
			case (Windows::Forms::Keys::Down):
				stepup();
				wezel->move(0,-3);
				savestat();
				break;
			case (Windows::Forms::Keys::Right):
				stepup();
				wezel->move(3,0);
				savestat();
				break;
			case (Windows::Forms::Keys::Left):
				stepup();
				wezel->move(-3,0);
				savestat();
				break;
			case (Windows::Forms::Keys::Insert):
				stepup();
				if(!wezel->father)
				{
					if(wezel->link==0){
					Node *tmp=new Node("",System::Drawing::Color::Black.ToArgb(),!wezel->strona);
					wezel->addChild("",tmp);
			
					tField=true;
					tF_X = tmp->getX()-100;
					tF_Y = tmp->getY();
					wezel->focus=false;
					wezel=tmp;
					edited = tmp;

				}
				}
				savestat();
				break;
			case (Windows::Forms::Keys::V):
				if(wezel->last->first)
					wezel->last->visibility();
				break;
		}
	}

	if(e->Control&&!e->Alt&&!e->Shift)
		switch(E){
			case (Windows::Forms::Keys::C):
//					SaveTo("C:/Documents and Settings/RedDot/tmp.rdt",wezel,NULL);
				break;

				
			case (Windows::Forms::Keys::V):
				{
/*					Node *ble=new Node("nazwa",0,true);
					ble=ReadFrom("C:/Documents and Settings/RedDot/tmp.rdt",NULL);
					ble->setInvisible();
//					ble->mirror();
					Paste(ble,wezel);
					ble->setVisible();
					wezel=ble;
					if(wezel->previous) wezel->previous->focus=false;
					wezel->focus=1;
*/				break;
				}
			case (Windows::Forms::Keys::Up):{
				stepup();	
				wezel->nodeUp();
					savestat();
											
				break;
				}
			case (Windows::Forms::Keys::Down):{
				stepup();	
				wezel->nodeDown();
					savestat();
											 
				break;
				 }
			case (Windows::Forms::Keys::Left):
				{
					if(wezel->strona&&wezel->father&&wezel->father->father&&wezel->father->father->father){
						stepup();
					wezel->nodeLeft();
					savestat();}
				break;
				}
			case (Windows::Forms::Keys::Right):
				if(!wezel->strona&&wezel->father&&wezel->father->father&&wezel->father->father->father){
					stepup();
					wezel->nodeLeft();				
					savestat();}

				break;
			case (Windows::Forms::Keys::Enter):
			{  
				stepup();
				if(!wezel->father) this->KeyDown(gcnew KeyEventArgs(Keys::F2)); 
				else {
					AddNodeDialog ^dialog1 = gcnew AddNodeDialog(1,tree,wezel);
					dialog1->ShowDialog();
					if(wezel)
						if(wezel->father&&wezel->next) wezel=wezel->next;
					else 
					  if(!wezel->father)	
						wezel=wezel->last;
					  else 
							  wezel = wezel->father->last;

				savestat();	
				}	
			break;
			}	
			case (Windows::Forms::Keys::Insert): 
             {	stepup();
				 if(wezel->link==0){
				AddNodeDialog ^ dialog = gcnew AddNodeDialog(0,tree,wezel);
				dialog->ShowDialog();
				if(wezel&&wezel->last) wezel=wezel->last;
				
				savestat();
				 }
			    break;
			}
	} 
	}
System::Drawing::Point getXboundaries(Node* tree)
{
	System::Drawing::Point tmpRet=System::Drawing::Point(tree->getX(),tree->getX()+tree->getWidth()),tmptmp=tmpRet;
	if (tree->first)
		for (Node* tmp=tree->first;tmp;tmp=tmp->next)
		{
			tmptmp=getXboundaries(tmp);
			if (tmptmp.X<tmpRet.X)
				tmpRet.X=tmptmp.X;
			if (tmptmp.Y>tmpRet.Y)
				tmpRet.Y=tmptmp.Y;
		}
	return tmpRet;
}
System::Drawing::Point getYboundaries(Node* tree)
{
	System::Drawing::Point tmpRet=System::Drawing::Point(tree->getY(),tree->getY()+tree->getHeight()),tmptmp=tmpRet;
	if (tree->first)
		for (Node* tmp=tree->first;tmp;tmp=tmp->next)
		{
			tmptmp=getYboundaries(tmp);
			if (tmptmp.X<tmpRet.X)
				tmpRet.X=tmptmp.X;
			if (tmptmp.Y>tmpRet.Y)
				tmpRet.Y=tmptmp.Y;
		}
	return tmpRet;
}



void Keylistner::calculateDisplacementBoundaries()
{
	System::Drawing::Point tmpX,tmpY;
	tmpX=getXboundaries(this->getTree());
	this->minPosH=tmpX.X-150;
	this->maxPosH=tmpX.Y+150;
	tmpY=getYboundaries(this->getTree());
	this->minPosV=tmpY.X-150;
	this->maxPosV=tmpY.Y+150;

	
}
